from django.conf import settings
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.utils.deprecation import MiddlewareMixin


class UserInfo(object):
    def __init__(self, role, name, id):
        self.role = role
        self.name = name
        self.id = id
        self.menu_name = None
        self.menu_nav_list = []


class AuthMiddleware(MiddlewareMixin):
    def is_white_url(self, request):
        if request.path_info in settings.NO_LOGIN_URL:
            return True

    def process_request(self, request):
        """ 校验用户是否已登录 """
        # 1. 白名单网址不做校验
        if self.is_white_url(request):
            return

        # 2. session中获取用户信息，有则已登录，无则未登录
        user_dict = request.session.get(settings.MY_SESSION_KEY)

        # 3. 未登录
        if not user_dict:
            return redirect(settings.LOGIN_URL)

        # 4. 已登录。将user信息添加到request对象中，方便后面的中间件取值。字典没有键名提示，转格式为对象。
        request.my_user = UserInfo(**user_dict)
        return

    def process_view(self, request, view_func, view_args, view_kwargs):
        if self.is_white_url(request):
            return
        # 1. 获取用户当前角色的所有权限
        role = request.my_user.role
        permission_dict = settings.MY_PERMISSION.get(role)

        # 2. 获取用户当前要访问的权限
        current_url_name = request.resolver_match.url_name

        # 3. 判断是否有权限
        if current_url_name not in permission_dict:
            is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest'
            if is_ajax:
                return JsonResponse({'status': False, 'detail': '无权访问'})
            return render(request, 'permission_deny.html')

        # 4. 有权限
        menu_nav_list = []
        menu_nav_list.append(permission_dict.get(current_url_name).get('text'))

        menu_name = current_url_name
        while permission_dict.get(menu_name).get('parent'):
            menu_name = permission_dict.get(menu_name).get('parent')
            menu_nav_list.append(permission_dict.get(menu_name).get('text'))
        # 4.1 设置关联菜单名称
        request.my_user.menu_name = menu_name
        # 4.2 设置菜单导航列表的值
        menu_nav_list.reverse()
        request.my_user.menu_nav_list = menu_nav_list
